package cn.lili.modules.order.cart.render.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
import cn.lili.common.enums.PromotionTypeEnum;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.modules.member.client.RedPackUserClient;
import cn.lili.modules.member.entity.dos.RedPackUser;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.order.cart.entity.dto.TradeDTO;
import cn.lili.modules.order.cart.entity.enums.RenderStepEnums;
import cn.lili.modules.order.cart.entity.vo.CartSkuVO;
import cn.lili.modules.order.cart.entity.vo.CartVO;
import cn.lili.modules.order.cart.render.CartRenderStep;
import cn.lili.modules.order.order.entity.dto.PriceDetailDTO;
import cn.lili.modules.payment.client.WalletPointClient;
import cn.lili.modules.promotion.client.KanjiaActivityGoodsClient;
import cn.lili.modules.promotion.client.PromotionGoodsClient;
import cn.lili.modules.promotion.client.PromotionsClient;
import cn.lili.modules.promotion.client.RedPackGoodsClient;
import cn.lili.modules.promotion.entity.dto.search.KanjiaActivitySearchParams;
import cn.lili.modules.promotion.entity.enums.KanJiaStatusEnum;
import cn.lili.modules.promotion.entity.vos.PromotionSkuVO;
import cn.lili.modules.promotion.entity.vos.kanjia.KanjiaActivityVO;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 购物促销信息渲染实现
 *
 * @author Chopper
 * @since 2020-07-02 14:47
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SkuPromotionRender implements CartRenderStep {


    private final PromotionsClient promotionsClient;


    private final WalletPointClient walletPointClient;

    private final PromotionGoodsClient promotionGoodsClient;

    private final KanjiaActivityGoodsClient kanjiaActivityGoodsClient;

    private final Cache cache;

    private final RedPackUserClient redPackUserClient;

    private final RedPackGoodsClient redPackGoodsClient;

    @Override
    public RenderStepEnums step() {
        return RenderStepEnums.SKU_PROMOTION;
    }

    @Override
    public void render(TradeDTO tradeDTO) {
        //基础价格渲染
        renderBasePrice(tradeDTO);
        //渲染单品促销
        renderSkuPromotion(tradeDTO);
        //检查促销库存
        checkPromotionQuantity(tradeDTO);
    }

    /**
     * 基础价格渲染
     *
     * @param tradeDTO 购物车视图
     */
    private void renderBasePrice(TradeDTO tradeDTO) {
        tradeDTO.getCartList().forEach(
                cartVO -> cartVO.getCheckedSkuList().forEach(cartSkuVO -> {
                    PriceDetailDTO priceDetailDTO = cartSkuVO.getPriceDetailDTO();
                    priceDetailDTO.setOriginalPrice(CurrencyUtil.mul(cartSkuVO.getPurchasePrice(), cartSkuVO.getNum()));
                    if (null != cartSkuVO.getPromotionTypeEnum()
                            && (PromotionTypeEnum.PINTUAN.name().equals(cartSkuVO.getPromotionTypeEnum().name())
                            || PromotionTypeEnum.SECKILL.name().equals(cartSkuVO.getPromotionTypeEnum().name())
                            || PromotionTypeEnum.POINTS_GOODS.name().equals(cartSkuVO.getPromotionTypeEnum().name())
                            || PromotionTypeEnum.RED_PACK_GOODS.name().equals(cartSkuVO.getPromotionTypeEnum().name())
                    )) {
                        log.info("红包商品价格：{}", cartSkuVO.getSubTotal());
                        priceDetailDTO.setGoodsPrice(cartSkuVO.getSubTotal());
                    } else {
                        if (!tradeDTO.getIsVip() && !StringUtils.isNotEmpty(cartSkuVO.getGoodsSku().getMhId())) {
                            log.info("价格：{}", cartSkuVO.getSubTotal());
                            log.info("价格2：{}", cartSkuVO.getGoodsSku().getFyVipPrice());
                            if (cartSkuVO.getGoodsSku().getFyVipPrice() == null || Double.compare(cartSkuVO.getGoodsSku().getFyVipPrice(), 0.0) == 0) {
                                priceDetailDTO.setGoodsPrice(cartSkuVO.getSubTotal());
                            }
                        }
                    }

                    priceDetailDTO.setDiscountPrice(CurrencyUtil.sub(priceDetailDTO.getOriginalPrice(), cartSkuVO.getSubTotal()));
                })
        );
    }


    /**
     * 渲染单品优惠 积分/拼团/秒杀/砍价
     *
     * @param tradeDTO 购物车视图
     */
    private void renderSkuPromotion(TradeDTO tradeDTO) {

        boolean isPromotion = false;
        //赋予购物车商品默认优惠信息
        //循环购物车
        for (CartVO cartVO : tradeDTO.getCartList()) {
            //循环sku
            for (CartSkuVO cartSkuVO : cartVO.getCheckedSkuList()) {

                //如果渲染单独促销类型商品，则跳过
                if (Boolean.TRUE.equals(handlerSignPromotion(cartSkuVO))) {
                    isPromotion = true;
                    continue;
                }

                //赋予商品促销信息
                for (Map.Entry<String, Object> entry : cartSkuVO.getPromotionMap().entrySet()) {
                    if (ignorePromotion(entry.getKey())) {
                        continue;
                    }

                    JSONObject promotionsObj = JSONUtil.parseObj(entry.getValue());
                    PromotionSkuVO promotionSkuVO = new PromotionSkuVO(entry.getKey().split("-")[0], promotionsObj.get("id", String.class));
                    cartSkuVO.setSubTotal(CurrencyUtil.mul(cartSkuVO.getPurchasePrice(), cartSkuVO.getNum()));
                    cartSkuVO.getPriceDetailDTO().setGoodsPrice(cartSkuVO.getSubTotal());
                    cartSkuVO.getPriceDetailDTO().getJoinPromotion().add(promotionSkuVO);
                }

                if (null != cartSkuVO.getPromotionTypeEnum()) {
                    isPromotion = true;
                }
            }
        }
        if (!isPromotion) {
            tradeDTO.setPromotionType(null);
        }
    }

    /**
     * 渲染单品促销
     *
     * @param cartSku sku信息
     * @return 是否渲染单品活动
     */
    private Boolean handlerSignPromotion(CartSkuVO cartSku) {
        //如果没有指定促销则返回 不进行渲染
        if (cartSku.getPromotionTypeEnum() == null) {
            return false;
        }
        switch (cartSku.getPromotionTypeEnum()) {
            case KANJIA -> {
                KanjiaActivitySearchParams kanjiaActivitySearchParams = new KanjiaActivitySearchParams();
                kanjiaActivitySearchParams.setGoodsSkuId(cartSku.getGoodsSku().getId());
                kanjiaActivitySearchParams.setMemberId(Objects.requireNonNull(UserContext.getCurrentUser()).getExtendId());
                kanjiaActivitySearchParams.setStatus(KanJiaStatusEnum.SUCCESS.name());
                KanjiaActivityVO kanjiaActivityVO = promotionsClient.getKanjiaActivityVO(kanjiaActivitySearchParams);
                //可以砍价金额购买，则处理信息
                if (Boolean.TRUE.equals(kanjiaActivityVO.getPass())) {
                    cartSku.setPromotionId(kanjiaActivityVO.getId());
                    cartSku.setPurchasePrice(kanjiaActivityVO.getPurchasePrice());
                    cartSku.setSubTotal(kanjiaActivityVO.getPurchasePrice());
                    cartSku.getPriceDetailDTO().setGoodsPrice(kanjiaActivityVO.getPurchasePrice());
                }

                PromotionSkuVO promotionSkuVO = new PromotionSkuVO(PromotionTypeEnum.KANJIA.name(), cartSku.getPromotionId());
                cartSku.getPriceDetailDTO().getJoinPromotion().add(promotionSkuVO);
                return true;
            }
            case PINTUAN -> {
                PromotionSkuVO promotionSkuVO = new PromotionSkuVO(PromotionTypeEnum.PINTUAN.name(), cartSku.getPromotionId());
                cartSku.getPriceDetailDTO().getJoinPromotion().add(promotionSkuVO);
                return true;
            }
            case POINTS_GOODS -> {
                cartSku.getPriceDetailDTO().setPayPoint(cartSku.getPoints());
                PromotionSkuVO promotionSkuVO = new PromotionSkuVO(PromotionTypeEnum.POINTS_GOODS.name(), cartSku.getPromotionId());
                cartSku.getPriceDetailDTO().getJoinPromotion().add(promotionSkuVO);

                if (walletPointClient.getUserPoint(UserContext.getCurrentId()) < cartSku.getPoints()) {
                    throw new ServiceException(ResultCode.POINT_NOT_ENOUGH);
                }
                return true;
            }
            case RED_PACK_GOODS -> {
                cartSku.getPriceDetailDTO().setPayRedPack(cartSku.getRedPack());
                PromotionSkuVO promotionSkuVO = new PromotionSkuVO(PromotionTypeEnum.RED_PACK_GOODS.name(), cartSku.getPromotionId());
                cartSku.getPriceDetailDTO().getJoinPromotion().add(promotionSkuVO);
                RedPackUser redPackUser = redPackUserClient.getRedPackUser(UserContext.getCurrentId());
                if (null == redPackUser || 0 == redPackUser.getStatus()) {
                    throw new ServiceException(ResultCode.USER_RED_PACK_ERROR);
                }
                if (redPackUser.getRedPackCount() < cartSku.getRedPack()) {
                    throw new ServiceException(ResultCode.USER_RED_PACK_COUNT_ERROR);
                }
                return true;
            }
            default -> {
                return false;
            }
        }
    }


    /**
     * 检查促销库存
     *
     * @param tradeDTO 购物车视图
     */
    private void checkPromotionQuantity(TradeDTO tradeDTO) {
        for (CartSkuVO cartSkuVO : tradeDTO.getCheckedSkuList()) {
            List<PromotionSkuVO> joinPromotion = cartSkuVO.getPriceDetailDTO().getJoinPromotion();
            if (!joinPromotion.isEmpty()) {
                for (PromotionSkuVO promotionSkuVO : joinPromotion) {
                    this.checkPromotionGoodsQuantity(cartSkuVO, promotionSkuVO);
                }
            }
        }
    }

    private void checkPromotionGoodsQuantity(CartSkuVO cartSkuVO, PromotionSkuVO promotionSkuVO) {
        String promotionGoodsStockCacheKey = PromotionGoodsClient.getPromotionGoodsStockCacheKey(PromotionTypeEnum.valueOf(promotionSkuVO.getPromotionType()), promotionSkuVO.getActivityId(), cartSkuVO.getGoodsSku().getId());
        Object quantity = cache.get(promotionGoodsStockCacheKey);

        if (quantity == null) {
            //如果促销有库存信息
            PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(promotionSkuVO.getPromotionType());
            switch (promotionTypeEnum) {
                case KANJIA:
                    quantity = kanjiaActivityGoodsClient.getKanjiaGoodsBySkuId(cartSkuVO.getGoodsSku().getId()).getStock();
                    break;
                case POINTS_GOODS:
                    quantity = promotionsClient.getPointsGoodsDetailBySkuId(cartSkuVO.getGoodsSku().getId()).getActiveStock();
                    break;
                case RED_PACK_GOODS:
                    quantity = redPackGoodsClient.getRedPackGoodsDetailBySkuId(cartSkuVO.getGoodsSku().getId()).getActiveStock();
                    log.info("红包广场库存检测：{}", JSON.toJSONString(quantity));
                    break;
                case SECKILL:
                case PINTUAN:
                    log.info("promotionSkuVO == {} , cartSkuVO == {}", com.alibaba.fastjson.JSONObject.toJSONString(promotionSkuVO), com.alibaba.fastjson.JSONObject.toJSONString(cartSkuVO));
                    boolean isNotNull = StringUtils.isNotEmpty(promotionSkuVO.getActivityId()) && StringUtils.isNotEmpty(promotionSkuVO.getPromotionType()) && cartSkuVO.getGoodsSku() != null && StringUtils.isNotEmpty(cartSkuVO.getGoodsSku().getId());
                    if (isNotNull) {
                        quantity = promotionGoodsClient.getPromotionGoodsStock(PromotionTypeEnum.valueOf(promotionSkuVO.getPromotionType()), promotionSkuVO.getActivityId(), cartSkuVO.getGoodsSku().getId());
                    }
                    break;
                default:
                    return;
            }
        }

        log.info("红包广场库存检测2：{}", cartSkuVO.getNum());
        if (quantity != null && cartSkuVO.getNum() > (Integer) quantity) {//设置购物车未选中
            cartSkuVO.setChecked(false);
            //设置失效消息
            cartSkuVO.setErrorMessage("促销商品库存不足,现有库存数量[" + quantity + "]");
        }
    }

    /**
     * 购物车促销类型
     */
    private boolean ignorePromotion(String promotionKey) {

        // 忽略积分活动活动 忽略砍价活动 忽略优惠券活动 忽略拼团活动 忽略红包活动
        return promotionKey.contains(PromotionTypeEnum.POINTS_GOODS.name())
                || promotionKey.contains(PromotionTypeEnum.RED_PACK_GOODS.name())
                || promotionKey.contains(PromotionTypeEnum.KANJIA.name())
                || promotionKey.contains(PromotionTypeEnum.COUPON.name())
                || promotionKey.contains(PromotionTypeEnum.PINTUAN.name());
    }

}
